﻿using AutoMapper;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Stackoverflow.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace Stackoverflow.Web.Controllers
{
    [Authorize]
    public class HomeController : System.Web.Mvc.Controller
    {
        private const string PASSWORD = "123456";
        public UserManager<IdentityUser> UserManager { get; private set; }

        private IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContext.GetOwinContext().Authentication;
            }
        }

        public HomeController()
            : this(Startup.UserManagerFactory())
        { 
        
        }

        public HomeController(UserManager<IdentityUser> userManager)
        {
            UserManager = userManager;
        }

        public ActionResult Index()
        {
            var serializeSettings = new JsonSerializerSettings()
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };

            var userId = User.Identity.GetUserId();
            Session["UserId"] = userId;
            ViewBag.Account = Newtonsoft.Json.JsonConvert.SerializeObject(userId);

            return View();
        }

        [AllowAnonymous]
        public ActionResult Register(string userType = null)
        {
            if (userType == "customer")
            {
                ViewBag.IsCustomer = true;
            }

            ViewBag.Title = "Register page";
            return View();
        }

        //
        // GET: /Account/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.Title = "Logon page";
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }

        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var user = await UserManager.FindAsync(model.UserName, PASSWORD);

                if (user != null)
                {
                    if (user.LockoutEnabled)
                    {
                        ModelState.AddModelError("", "This user is locked");
                    }
                    else
                    {
                        await SignInAsync(user, true);
                        return RedirectToLocal(returnUrl);
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Invalid username or password.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        [AllowAnonymous]
        [HttpPost]
        public async Task<ActionResult> Register(RegisterBindingModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            IdentityUser user = new IdentityUser
            {
                UserName = model.UserName
            };

            var result = await UserManager.CreateAsync(user, PASSWORD);

            if (!result.Succeeded)
            {
                ProcessErrorResult(result);
                return View(model);
            }

            ViewBag.Message = "Registration is successful";

            return View(model);
        }

        public ActionResult Logout()
        {
            AuthenticationManager.SignOut();
            return RedirectToAction("LogIn");
        }

        private async Task SignInAsync(IdentityUser user, bool isPersistent)
        {
            AuthenticationManager.SignOut();
            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
        }

        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }

        private void ProcessErrorResult(IdentityResult result)
        {
            if (result == null)
            {
                ModelState.AddModelError("", "Result is null");
            }

            if (!result.Succeeded)
            {
                if (result.Errors != null)
                {
                    foreach (string error in result.Errors)
                    {
                        ModelState.AddModelError("", error);
                    }
                }
            }
        }
    }
}
